﻿using Microsoft.Xna.Framework;
using System.Collections.Generic;
using XNAFight.Engine.Inputs;
using System;

namespace XNAFight.Scene.Core
{
    public class ControlerSelection
    {
        private Controler controler;
        private int selection_x;
        private int selection_y;
        private int id_player;
        private bool active;

        public Controler Controler
        {
            get { return controler; }
        }
        public int SelectionX
        {
            get { return selection_x; }
            set { selection_x = value; }
        }
        public int SelectionY
        {
            get { return selection_y; }
            set { selection_y = value; }
        }
        public int PlayerID
        {
            get { return id_player; }
            set { id_player = value; }
        }
        public bool Active
        {
            get { return active; }
            set { active = value; }
        }

        public ControlerSelection(Controler _controler, int _selection_x, int _selection_y, int _player_id)
        {
            controler = _controler;
            selection_x = _selection_x;
            selection_y = _selection_y;
            id_player = _player_id;
            active = true;
        }
    }

    public class MultiMenuScreen : Screen
    {
        private string title;
        protected Vector2 title_pos;
        protected MenuItem[,] items;
        protected int default_selection_x, default_selection_y;
        private List<ControlerSelection> controlers_selections;
        
        #region EVENTS

        public event EventHandler<EventArgs<ControlerSelection>> CancellingBy;

        private void OnCancellingBy(ControlerSelection _selection)
        {
            if (CancellingBy != null)
                CancellingBy(this, new EventArgs<ControlerSelection>(_selection));
        }

        #endregion

        public MultiMenuScreen(string _title) 
            : base()
        {
            items = null;
            default_selection_x = 0;
            default_selection_y = 0;
            title = _title;
            title_pos = new Vector2(20, 20);
            controlers_selections = new List<ControlerSelection>();
        }

        public override void HandleInputs()
        {
            for (int i = 0; i < controlers_selections.Count; i++)
            {
                if (controlers_selections[i].Active)
                {
                    if (MenuInputInterpreter.isMenuUp(controlers_selections[i].Controler))
                    {
                        do
                        {
                            controlers_selections[i].SelectionY--;
                            if (controlers_selections[i].SelectionY < 0)
                                controlers_selections[i].SelectionY = items.GetLength(1) - 1;
                        }
                        while (items[controlers_selections[i].SelectionX, controlers_selections[i].SelectionY] == null);
                    }
                    if (MenuInputInterpreter.isMenuDown(controlers_selections[i].Controler))
                    {
                        do
                        {
                            controlers_selections[i].SelectionY++;
                            if (controlers_selections[i].SelectionY >= items.GetLength(1))
                                controlers_selections[i].SelectionY = 0;
                        }
                        while (items[controlers_selections[i].SelectionX, controlers_selections[i].SelectionY] == null);
                    }
                    if (MenuInputInterpreter.isMenuLeft(controlers_selections[i].Controler))
                    {
                        do
                        {
                            controlers_selections[i].SelectionX--;
                            if (controlers_selections[i].SelectionX < 0)
                                controlers_selections[i].SelectionX = items.GetLength(0) - 1;
                        }
                        while (items[controlers_selections[i].SelectionX, controlers_selections[i].SelectionY] == null);
                    }
                    if (MenuInputInterpreter.isMenuRight(controlers_selections[i].Controler))
                    {
                        do
                        {
                            controlers_selections[i].SelectionX++;
                            if (controlers_selections[i].SelectionX >= items.GetLength(0))
                                controlers_selections[i].SelectionX = 0;
                        }
                        while (items[controlers_selections[i].SelectionX, controlers_selections[i].SelectionY] == null);
                    }

                    // Validation d'un element de menu
                    if (MenuInputInterpreter.isMenuItemSelected(controlers_selections[i].Controler))
                        OnItemSelected(controlers_selections[i]);
                }
                // Annulation
                if (MenuInputInterpreter.isMenuCanceled(controlers_selections[i].Controler))
                {
                    OnCancellingBy(controlers_selections[i]);
                }
            }
        }
        
        public override void Update(GameTime _game_time)
        {
            base.Update(_game_time);

            if (items != null)
            {
                // MaJ des éléments de menu
                for (int x = 0; x < items.GetLength(0); x++)
                {
                    for (int y = 0; y < items.GetLength(1); y++)
                    {
                        List<int> player_ids = new List<int>();
                        for (int i = 0; i < controlers_selections.Count; i++)
                        {
                            if ((controlers_selections[i].SelectionX == x) && (controlers_selections[i].SelectionY == y))
                                player_ids.Add(controlers_selections[i].PlayerID);
                        }

                        if (items[x, y] != null)
                            items[x, y].Update(_game_time, player_ids);
                    }
                }
            }
        }

        public override void Draw(GameTime _game_time)
        {
            CommonContent.SpriteBatch.Begin();

            // Affichage de l'intitulé
            CommonContent.SpriteBatch.DrawString(CommonContent.DefaultFont, title, title_pos, Color.Black);
            if (items != null)
            {
                // Affichage des éléments de menu
                for (int x = 0; x < items.GetLength(0); x++)
                {
                    for (int y = 0; y < items.GetLength(1); y++)
                    {
                        List<int> player_ids = new List<int>();
                        for (int i = 0; i < controlers_selections.Count; i++)
                        {
                            if ((controlers_selections[i].Active) && (controlers_selections[i].SelectionX == x) && (controlers_selections[i].SelectionY == y))
                                player_ids.Add(controlers_selections[i].PlayerID);
                        }

                        if (items[x, y] != null)
                            items[x, y].Draw(_game_time, player_ids);
                    }
                }
            }

            CommonContent.SpriteBatch.End();
        }
        
        protected void OnItemSelected(ControlerSelection _selection)
        {
            if (items != null)
                if (items[_selection.SelectionX, _selection.SelectionY] != null)
                    items[_selection.SelectionX, _selection.SelectionY].OnItemSelected(_selection);
        }

        public void AddControler(Controler _controler, int _player_id)
        {
            controlers_selections.Add(new ControlerSelection(_controler, default_selection_x, default_selection_y, _player_id));
        }
        public void RemoveControler(ControlerSelection _selection)
        {
            controlers_selections.Remove(_selection);
        }

        public ControlerSelection getSelectionFromPlayerID(int _player_id)
        {
            int i = 0;
            while (i < controlers_selections.Count && _player_id != controlers_selections[i].PlayerID)
            {
                i++;
            }

            if (i < controlers_selections.Count)
                return controlers_selections[i];

            return null;
        }
    }
}
